/******************************************************************************
                         COPYRIGHT 1955-2008 by BUPT ISC.
                        北京邮电大学信息安全中心 版权所有
                           Web: http://www.bupt.edu.cn
 *******************************************************************************/
/*******************************************************************************
  文件名： mqueue.c
  项目：   
  模块：   common
  作者：   huangwei
  版本：   0.1
  创建于:  2008-12-23 
  描述：
    多线程安全队列的操作方法实现

  修改历史：
  日期： 修改人： 修改描述：
  
 *********************************************************************************/


#include <stdio.h>
#include <malloc.h>

#include "queue.h"
#include "mqueue.h"



 
/******************************************************************************
  函数名：initMQueue
  功能描述：
    初始化多线程安全队列结构体
    
  输入参数：
    MQUEUE_T * 待初始化队列

  输出参数：
    无

  返回值：
    执行成功时返回bool变量true，失败时返回bool变量false
 *****************************************************************************/
bool initMQueue(MQUEUE_T *pstMQueue, unsigned int iCapacity)
{
    if (pstMQueue == NULL)
    {
        return false;
    }
    else
    {
        if (initQueue(pstMQueue->pstQueue) == false)/*初始化队列 */
        {
            return false;
        }
        else
        {
            pthread_mutex_init(&pstMQueue->mutex, NULL);
            pthread_cond_init(&pstMQueue->cond_empty, NULL);/*初始化线程的条件*/
            pthread_cond_init(&pstMQueue->cond_full, NULL);
            pstMQueue->iMQueueCapacity = iCapacity;
        }
    }

    return true;
}
/******************************************************************************
  函数名：initMQueue
  功能描述：
    初始化多线程安全队列结构体
    
  输入参数：
    MQUEUE_T * 待初始化队列

  输出参数：
    无

  返回值：
    执行成功时返回bool变量true，失败时返回bool变量false
 *****************************************************************************/
MQUEUE_T * initMQueueAll(MQUEUE_T *pstMQueue, unsigned int iCapacity)
{
    if (pstMQueue != NULL)
        return pstMQueue;

    pstMQueue = (MQUEUE_T *)malloc(sizeof(MQUEUE_T));
    if (pstMQueue == NULL)
    {
        printf("pstMQueue malloc failed!");
        return NULL;
    }
    pstMQueue->pstQueue = (QUEUE *)malloc(sizeof(QUEUE));
    if (pstMQueue->pstQueue == NULL)
    {
        printf("pstMQueue->pstQueue malloc failed!");
        return NULL;
    }
    if (initMQueue(pstMQueue, iCapacity) == false)
    {
        free(pstMQueue->pstQueue);
        free(pstMQueue);
        fprintf(stderr, "initMQueueAll(pstMQueue) error\n"); 
        return NULL; /* TOFIX 调用资源释放函数*/
    }

    return pstMQueue;
}



/******************************************************************************
  函数名：enMQueue
  功能描述：
    在队列中插入节点
    
  输入参数：
    MQUEUE_T * 待插入队列
    void *     节点
    int        节点长度 

  输出参数：
    无

  返回值：
    执行成功时返回bool变量true，失败时返回bool变量false
 *****************************************************************************/
bool enMQueue(MQUEUE_T *pstMQueue, void *pQueueData, int iDataLen)
{
    pthread_mutex_lock(&(pstMQueue->mutex));
    while (pstMQueue->pstQueue->iCount == pstMQueue->iMQueueCapacity)
    {
        pthread_cond_wait(&(pstMQueue->cond_full), &(pstMQueue->mutex));
    }
    if (enQueue(pstMQueue->pstQueue, pQueueData, iDataLen) == false)
    {
        pthread_mutex_unlock(&(pstMQueue->mutex));
        return false;
    }

    pthread_cond_signal(&(pstMQueue->cond_empty));
    pthread_mutex_unlock(&(pstMQueue->mutex));

    return true;
}

/******************************************************************************
  函数名：deMQueue
  功能描述：
    从队列中读出一个节点
    
  输入参数：
    MQUEUE_T * 待读取队列
    NODE *     存放取出节点的指针

  输出参数：
    NODE *     取出的节点

  返回值：
    执行成功时返回bool变量true，失败时返回bool变量false
 *****************************************************************************/
bool deMQueue(MQUEUE_T *pstMQueue, NODE *pstNode)
{
    pthread_mutex_lock(&(pstMQueue->mutex));
    while (pstMQueue->pstQueue->iCount == 0)
    {
        pthread_cond_wait(&(pstMQueue->cond_empty), &(pstMQueue->mutex));
    }

    if (deQueue(pstMQueue->pstQueue, pstNode) == false)
    {
        pthread_mutex_unlock(&(pstMQueue->mutex));
        return false;        
    }   

    pthread_cond_signal(&(pstMQueue->cond_full));
    pthread_mutex_unlock(&(pstMQueue->mutex));

    return true;

}

/******************************************************************************
  函数名：freeMQueue
  功能描述：
    释放队列所有内存
    
  输入参数：
    MQUEUE_T * 待释放内存队列

  输出参数：
    无

  返回值：
    无
 *****************************************************************************/
void freeMQueue(MQUEUE_T *pstMQueue)
{
    if (pstMQueue == NULL)
    {
        return;
    }
    freeQueue(pstMQueue->pstQueue);
    free(pstMQueue->pstQueue);
    pstMQueue->pstQueue = NULL;
    pthread_mutex_destroy(&pstMQueue->mutex);
    pthread_cond_destroy(&pstMQueue->cond_empty);
    pthread_cond_destroy(&pstMQueue->cond_full);
    free(pstMQueue);
    
    return;
}
